package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.FlowTenantService;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.DateUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.common.ErrorCode;
import com.iwhalecloud.citybrain.flow.platform.manager.common.ResponseResult;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.DeleteVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowBusi;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowUser;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.app.FlowApp;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.app.FlowAppAddVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.app.FlowAppAuthorizeUserVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.app.FlowAppBusiSimpleVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.app.FlowAppDetailVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.app.FlowAppQueryVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.app.FlowAppUpdateVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.tenant.FlowTenantInfoVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.tenant.FlowUserTenantVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowAppRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowBusiRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowTenantRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.UserRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.common.FlowCommonCodeConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Controller - 应用
 *
 * @author lilh
 * @date 2019-01-22 15:34
 */
@RestController
@RequestMapping("/app")
@Api(value = "应用管理", tags = {"应用管理接口"})
public class FlowAppController {

    @Autowired
    private FlowAppRepository flowAppRepository;

    @Autowired
    private FlowBusiRepository busiService;

    @Autowired
    private FlowTenantRepository flowTenantRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private FlowTenantService tenantService;

    /**
     * 增加应用
     */
    @ApiOperation("增加应用")
    @PostMapping("/add")
    public ResponseResult add(@RequestBody @Validated FlowAppAddVo flowAppAddVo) {
        FlowTenantInfoVo tenantInfo = flowTenantRepository.detail(flowAppAddVo.getTenantId());
        if (Objects.isNull(tenantInfo)) {
            return ResponseResult.fail(ErrorCode.NOT_EXIST.errCode(), "租户不存在");
        }
        //FlowAppInfoExample appInfoExample = new FlowAppInfoExample();
        //appInfoExample.createCriteria().andAppCodeEqualTo(flowAppAddVo.getAppCode());
        List<FlowApp> appInfos = flowAppRepository.listByAppCode(flowAppAddVo.getAppCode());
        if (CollectionUtils.isEmpty(appInfos)) {
            return ResponseResult.success(flowAppRepository.insert(flowAppAddVo));
        } else {
            return ResponseResult.fail(ErrorCode.ALREADY_EXIST.errCode(), "应用编码已存在");
        }
    }

    /**
     * 应用列表
     */
    @ApiOperation("应用列表")
    @PostMapping("/listAll")
    public ResponseResult listAll() {
        List<FlowApp> flowAppInfos = flowAppRepository.listByAppId(null);
        Map<String, List<FlowAppBusiSimpleVo>> appMap = new HashMap<>(2);
        appMap.put("app", flowAppRepository.getAppAndBusiList(flowAppInfos));
        return ResponseResult.success(appMap);
    }

    /**
     * 应用业务列表
     */
    @ApiOperation("应用业务列表")
    @PostMapping("/list")
    public ResponseResult list() {
        List<FlowApp> flowAppInfos = flowAppRepository.listByAppId(null);
        Map<String, List<FlowAppBusiSimpleVo>> appMap = new HashMap<>(2);
        appMap.put("app", flowAppRepository.getAppAndBusiList(flowAppInfos));
        return ResponseResult.success(appMap);
    }

    /**
     * 更新
     */
    @ApiOperation("更新")
    @PostMapping("/edit")
    public ResponseResult update(@RequestBody @Validated FlowAppUpdateVo flowAppUpdateVo, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseResult.fail(ErrorCode.PARAMETER_ERROR.errCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return flowAppRepository.update(flowAppUpdateVo) > 0 ? ResponseResult.success() : ResponseResult.fail(FlowCommonCodeConstants.UPDATE_FAILED.getCode());
    }

    /**
     * 删除
     */
    @ApiOperation("删除")
    @PostMapping("/delete")
    public ResponseResult delete(@RequestBody DeleteVo deleteVo) {
        List<Integer> appIds = new ArrayList<>(1);
        appIds.add(deleteVo.getAppId());
        List<FlowBusi> flowBusiInfos = busiService.list(appIds);
        if (!CollectionUtils.isEmpty(flowBusiInfos)) {
            return ResponseResult.fail(ErrorCode.APP_HAS_BUSI.errCode(), ErrorCode.APP_HAS_BUSI.errMessage());
        }
        return ResponseResult.success(flowAppRepository.delete(deleteVo.getAppId()));
    }

    /**
     * 应用详情
     */
    @ApiOperation("应用详情")
    @PostMapping("/detail")
    public ResponseResult detail(@RequestBody FlowAppQueryVo appQueryVo) {
        FlowApp appInfo = flowAppRepository.detail(appQueryVo.getAppId());
        if (appInfo == null) {
            return ResponseResult.fail(ErrorCode.NOT_EXIST.errCode(), ErrorCode.NOT_EXIST.errMessage());
        }
        FlowTenantInfoVo tenantInfo = flowTenantRepository.detail(appInfo.getTenantId());
        FlowAppDetailVo appDetailVo = new FlowAppDetailVo();
        BeanUtils.copyProperties(appInfo, appDetailVo);
        appDetailVo.setTenantName(tenantInfo.getTenantName());
        appDetailVo.setCreateTime(appInfo.getCreateTime());
        return ResponseResult.success(appDetailVo);
    }

    /**
     * 获取租户-用户
     *
     * @param tenantId 租户id
     * @return 用户列表
     */
    @ApiOperation("获取租户-用户")
    @GetMapping("/listTenantUsers")
    public ResponseResult listTenantUsers(@RequestParam Integer tenantId) {
        List<FlowUserTenantVo> tenantUsers = tenantService.listUsersByTenantId(tenantId);
        if (!tenantUsers.isEmpty()) {
            //填充应用
            for (FlowUserTenantVo tenantUser : tenantUsers) {
                List<FlowApp> flowApps = flowAppRepository.listAppByTenantIdAndUserCode(tenantId, tenantUser.getUserCode());
                if (CollectionUtils.isNotEmpty(flowApps)) {
                    tenantUser.setAssociateApps(flowApps.stream().map(FlowApp::getAppName).collect(Collectors.joining(",")));
                }
            }
        }
        return ResponseResult.success(tenantUsers);
    }


    /**
     * 获取应用已授权用户列表
     */
    @ApiOperation("获取应用已授权用户列表")
    @PostMapping("/authorized/users")
    public ResponseResult authorizedUsers(@RequestBody FlowAppQueryVo flowAppQueryVo) {
        PageHelper.startPage(flowAppQueryVo.getPageNum(), flowAppQueryVo.getPageSize());
        List<FlowUser> userInfoList = userRepository.listAppAuthorizedUser(flowAppQueryVo.getAppId());
        PageInfo<FlowUser> pageInfo = new PageInfo<>(userInfoList);
        ResponseResult responseResult = ResponseResult.success(userInfoList);
        responseResult.setPageNum(flowAppQueryVo.getPageNum());
        responseResult.setPageSize(flowAppQueryVo.getPageSize());
        responseResult.setTotalCount(Long.valueOf(pageInfo.getTotal()).intValue());
        return responseResult;
    }

    /**
     * 应用给用户授权
     */
    @ApiOperation("应用给用户授权")
    @PostMapping("/authorize/user")
    public ResponseResult authorizeUser(@RequestBody FlowAppAuthorizeUserVo appAuthorizeUserVo) {
        return ResponseResult.success(flowAppRepository.authorize(appAuthorizeUserVo.getAppId(), appAuthorizeUserVo.getUserList()));
    }

    /**
     * 取消应用给用户的授权
     */
    @ApiOperation("取消应用给用户的授权")
    @PostMapping("/authorize/cancel")
    public ResponseResult authorizedCancel(@RequestBody FlowAppAuthorizeUserVo appAuthorizeUserVo) {
        return ResponseResult.success(flowAppRepository.authorizedCancel(appAuthorizeUserVo.getAppId(), appAuthorizeUserVo.getUserList()));
    }
}
